



#ifndef _PDF_DOCUMENT_H_
#define _PDF_DOCUMENT_H_

#include <wx/dynarray.h>
#include <wx/hashmap.h>
#include <wx/mstream.h>
#include <wx/string.h>
#include <wx/xml/xml.h>

#include "wx/pdfdocdef.h"
#include "wx/pdfarraytypes.h"
#include "wx/pdfarraydouble.h"
#include "wx/pdfcolour.h"
#include "wx/pdfencrypt.h"
#include "wx/pdfimage.h"
#include "wx/pdflinestyle.h"
#include "wx/pdflinks.h"
#include "wx/pdfproperties.h"

#define wxPDF_PRODUCER       wxT("wxPdfDocument 0.9.5")

#define wxPDF_EPSILON        1e-6

class WXDLLIMPEXP_FWD_PDFDOC wxPdfCoonsPatchMesh;

class WXDLLIMPEXP_FWD_PDFDOC wxPdfFont;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfFontDescription;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfFontDetails;

class WXDLLIMPEXP_FWD_PDFDOC wxPdfExtGState;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfGradient;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfInfo;

class WXDLLIMPEXP_FWD_PDFDOC wxPdfShape;

class WXDLLIMPEXP_FWD_PDFDOC wxPdfSpotColour;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfPattern;

class WXDLLIMPEXP_FWD_PDFDOC wxPdfCellContext;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfTable;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfIndirectObject;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfAnnotationWidget;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfTemplate;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfParser;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfObject;

class WXDLLIMPEXP_FWD_PDFDOC wxPdfArrayLayer;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfOcg;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfLayer;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfLayerMembership;
class WXDLLIMPEXP_FWD_PDFDOC wxPdfLayerGroup;

/// Hashmap class for offset values
WX_DECLARE_HASH_MAP_WITH_DECL(long, int, wxIntegerHash, wxIntegerEqual, wxPdfOffsetHashMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for document pages
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxMemoryOutputStream*, wxIntegerHash, wxIntegerEqual, wxPdfPageHashMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for document pages
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxSize, wxIntegerHash, wxIntegerEqual, wxPdfPageSizeMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for boolean values
WX_DECLARE_HASH_MAP_WITH_DECL(long, bool, wxIntegerHash, wxIntegerEqual, wxPdfBoolHashMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for double values
WX_DECLARE_HASH_MAP_WITH_DECL(long, double, wxIntegerHash, wxIntegerEqual, wxPdfDoubleHashMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for document links
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxPdfLink*, wxIntegerHash, wxIntegerEqual, wxPdfLinkHashMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for page links
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxArrayPtrVoid*, wxIntegerHash, wxIntegerEqual, wxPdfPageLinksMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for document annotations
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxArrayPtrVoid*, wxIntegerHash, wxIntegerEqual, wxPdfAnnotationsMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for document annotations
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxArrayPtrVoid*, wxIntegerHash, wxIntegerEqual, wxPdfFormAnnotsMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for form fields
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxPdfIndirectObject*, wxIntegerHash, wxIntegerEqual, wxPdfFormFieldsMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for templates
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxPdfTemplate*, wxIntegerHash, wxIntegerEqual, wxPdfTemplatesMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for font encoding differences
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxString*, wxIntegerHash, wxIntegerEqual, wxPdfStringHashMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for extended graphics states
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxPdfExtGState*, wxIntegerHash, wxIntegerEqual, wxPdfExtGStateMap, class WXDLLIMPEXP_PDFDOC);
WX_DECLARE_HASH_MAP_WITH_DECL(long, int, wxIntegerHash, wxIntegerEqual, wxPdfExtGSLookupMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for gradients
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxPdfGradient*, wxIntegerHash, wxIntegerEqual, wxPdfGradientMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for optional content groups
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxPdfOcg*, wxIntegerHash, wxIntegerEqual, wxPdfOcgMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for optional content groups
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxPdfLayerGroup*, wxIntegerHash, wxIntegerEqual, wxPdfLayerRGMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for file attachments
WX_DECLARE_HASH_MAP_WITH_DECL(long, wxArrayString*, wxIntegerHash, wxIntegerEqual, wxPdfAttachmentMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for core fonts
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(int, wxPdfCoreFontMap, class WXDLLIMPEXP_PDFDOC);

/// Hashmap class for core fonts
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(int, wxPdfNamedLinksMap, class WXDLLIMPEXP_PDFDOC);

/// Hash map class for used/embedded fonts
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPdfFontDetails*, wxPdfFontHashMap, class WXDLLIMPEXP_PDFDOC);

/// Hash map class for embedded images
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPdfImage*, wxPdfImageHashMap, class WXDLLIMPEXP_PDFDOC);

/// Hash map class for spot colours
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPdfSpotColour*, wxPdfSpotColourMap, class WXDLLIMPEXP_PDFDOC);

/// Hash map class for spot colours
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPdfPattern*, wxPdfPatternMap, class WXDLLIMPEXP_PDFDOC);

/// Hash map class for spot colours
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPdfIndirectObject*, wxPdfRadioGroupMap, class WXDLLIMPEXP_PDFDOC);

/// Hash map class for parsers
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPdfParser*, wxPdfParserMap, class WXDLLIMPEXP_PDFDOC);

#if WXPDFDOC_INHERIT_WXOBJECT
class WXDLLIMPEXP_PDFDOC wxPdfDocument : public wxObject
#else
class WXDLLIMPEXP_PDFDOC wxPdfDocument
#endif
{
public:
  /// Constructor
  
  wxPdfDocument(int orientation = wxPORTRAIT, 
                const wxString& unit = wxString(wxT("mm")), 
                wxPaperSize format = wxPAPER_A4);

  wxPdfDocument(int orientation, double pageWidth, double pageHeight,
                const wxString& unit = wxString(wxT("mm")));

  virtual ~wxPdfDocument();

  /// Set permissions as well as user and owner passwords.
  
  virtual void SetProtection(int permissions,
                             const wxString& userPassword = wxEmptyString,
                             const wxString& ownerPassword = wxEmptyString,
                             wxPdfEncryptionMethod encryptionMethod = wxPDF_ENCRYPTION_RC4V1,
                             int keyLength = 0);

  /// Set the image scale.
  
  virtual void SetImageScale(double scale);

  /// Returns the image scale.
  
  virtual double GetImageScale();

  /// Returns the page width in units.
  
  virtual double GetPageWidth();
  
  /// Returns the page height in units.
  
  virtual double GetPageHeight();
  
  /// Returns the page break margin.
  
  virtual double GetBreakMargin();
  
  /// Returns the scale factor (number of points in user unit).
  
  virtual double GetScaleFactor();

  /// Defines the left, top and right margins.
  
  virtual void SetMargins(double left, double top, double right = -1);
  
  /// Defines the left margin.
  
  virtual void SetLeftMargin(double margin);
  
  /// Returns the left margin.
  
  virtual double GetLeftMargin();

  /// Defines the top margin.
  
  virtual void SetTopMargin(double margin);
  
  /// Returns the top margin.
  
  virtual double GetTopMargin();

  /// Defines the right margin.
  
  virtual void SetRightMargin(double margin);

  /// Returns the right margin.
  
  virtual double GetRightMargin();

  /// Defines the cell margin.
  
  virtual void SetCellMargin(double margin);

  /// Returns the cell margin.
  
  virtual double GetCellMargin();

  /// Sets the height of a text line
  
  virtual void SetLineHeight(double height);

  /// Returns the height of a text line
  
  virtual double GetLineHeight();

  /// Enables or disables the automatic page breaking mode.
  
  virtual void SetAutoPageBreak(bool autoPageBreak, double margin = 0);

  /// Defines the way the document is to be displayed by the viewer.
  
  virtual void SetDisplayMode(wxPdfZoom zoom,
                              wxPdfLayout layout = wxPDF_LAYOUT_CONTINUOUS,
                              double zoomFactor = 100.);

  /// Enable or disable kerning.
  
  virtual void SetKerning(bool kerning);

  /// Activates or deactivates page compression.
  
  virtual void SetCompression(bool compress);

  /// Defines the viewer preferences.
  
  virtual void SetViewerPreferences(int preferences = 0);

  /// Defines the title of the document.
  
  virtual void SetTitle(const wxString& title);
  
  /// Defines the subject of the document.
  
  virtual void SetSubject(const wxString& subject);
  
  /// Defines the author of the document.
  
  virtual void SetAuthor(const wxString& author);

  /// Associates keywords with the document,
  
  virtual void SetKeywords(const wxString& keywords);
  
  /// Defines the creator of the document.
  
  virtual void SetCreator(const wxString& creator);
  
  /// Defines an alias for the total number of pages.
  
  virtual void AliasNbPages(const wxString& alias = wxString(wxT("{nb}")));

  /// This method begins the generation of the PDF document.
  
  virtual void Open();
  
  /// Terminates the PDF document.
  
  virtual void Close();
  
  /// Adds a new page to the document.
  
  virtual void AddPage(int orientation = -1);

  virtual void AddPage(int orientation, wxPaperSize format);

  virtual void AddPage(int orientation, double pageWidth, double pageHeight);

  /// This method is used to render the page header.
  
  virtual void Header();
  
  /// This method is used to render the page footer.
  
  virtual void Footer();
  
  /// Returns whether footer output is in progress
  
  virtual bool IsInFooter();
  
  /// Returns the current page number.
  
  virtual int  PageNo();
  
  /// Add spot colour
  
  virtual void AddSpotColour(const wxString& name, double cyan, double magenta, double yellow, double black);

  /// Add an image pattern
  
  virtual bool AddPattern(const wxString& patternName, const wxImage& image, double width, double height);

  /// Defines the colour used for all drawing operations.
  
  virtual void SetDrawColour(const unsigned char grayscale);
  
  /// Defines the colour used for all drawing operations.
  
  virtual void SetDrawColour(const wxColour& colour);
  
  /// Defines the colour used for all drawing operations.
  
  virtual void SetDrawColour(const wxPdfColour& colour);
  
  /// Defines the colour used for all drawing operations.
  
  virtual void SetDrawColour(const unsigned char red, const unsigned char green, const unsigned char blue);

  /// Defines the colour used for all drawing operations.
  
  virtual void SetDrawColour(double cyan, double magenta, double yellow, double black);

  /// Defines the <b>spot colour</b> used for all drawing operations.
  
  virtual void SetDrawColour(const wxString& name, double tint = 100);

  /// Defines the <b>pattern</b> used for all drawing operations.
  
  virtual void SetDrawPattern(const wxString& name);

  /// Gets the colour used for all drawing operations.
  
  virtual const wxPdfColour GetDrawColour();
  
  /// Defines the colour used for all filling operations.
  
  virtual void SetFillColour(const unsigned char grayscale);
  
  /// Defines the colour used for all filling operations.
  
  virtual void SetFillColour(const wxColour& colour);
  
  /// Defines the colour used for all filling operations.
  
  virtual void SetFillColour(const wxPdfColour& colour);
  
  /// Defines the colour used for all filling operations.
  
  virtual void SetFillColour(const unsigned char red, const unsigned char green, const unsigned char blue);

  /// Defines the colour used for all filling operations.
  
  virtual void SetFillColour(double cyan, double magenta, double yellow, double black);

  /// Defines the <b>spot colour</b> used for all filling operations.
  
  virtual void SetFillColour(const wxString& name, double tint = 100);

  /// Defines the <b>pattern</b> used for all filling operations.
  
  virtual void SetFillPattern(const wxString& name);

  /// Gets the named pattern as a colour.
  
  virtual const wxPdfColour GetPatternColour(const wxString& patternName);
  
  /// Gets the colour used for all filling operations.
  
  virtual const wxPdfColour GetFillColour();
  
  /// Defines the colour used for text.
  
  virtual void SetTextColour(const unsigned char grayscale);
  
  /// Defines the colour used for text.
  
  virtual void SetTextColour(const wxColour& colour);
  
  /// Defines the colour used for text.
  
  virtual void SetTextColour(const wxPdfColour& colour);
  
  /// Defines the colour used for text.
  
  virtual void SetTextColour(const unsigned char red, const unsigned char green, const unsigned char blue);

  /// Defines the colour used for text.
  
  virtual void SetTextColour(double cyan, double magenta, double yellow, double black);

  /// Defines the <b>spot colour</b> used for text.
  
  virtual void SetTextColour(const wxString& name, double tint = 100);

  /// Defines the <b>pattern</b> used for text output.
  
  virtual void SetTextPattern(const wxString& name);

  /// Gets the colour used for text output.
  
  virtual const wxPdfColour GetTextColour();
  
  /// Sets the text render mode
  
  virtual void SetTextRenderMode(wxPdfTextRenderMode mode = wxPDF_TEXT_RENDER_FILL);
  
  /// Returns the text render mode
  
  virtual wxPdfTextRenderMode GetTextRenderMode() const;

  /// Returns the length of a string in user unit.
  
  virtual double GetStringWidth(const wxString& s);

  /// Defines the line width.
  
  virtual void SetLineWidth(double width);

  /// Gets the current line width.
  
  virtual double GetLineWidth();

  /// Sets line style
  
  virtual void SetLineStyle(const wxPdfLineStyle& linestyle);

  /// Get current line style
  
  virtual const wxPdfLineStyle& GetLineStyle();

  /// Set the filling rule
  
  virtual void SetFillingRule(int rule = wxWINDING_RULE);

  /// Get the current filling rule
  
  virtual int GetFillingRule();

  /// Draws a line between two points.
  
  virtual void Line(double x1, double y1, double x2, double y2);
  
  /// Draws an arrow line between two points.
  
  virtual void Arrow(double x1, double y1, double x2, double y2, double linewidth, double height, double width);

  /// Outputs a rectangle.
  
  virtual void Rect(double x, double y, double w, double h, int style = wxPDF_STYLE_DRAW);

  /// Draws a rounded rectangle
  
  virtual void RoundedRect(double x, double y, double w, double h,
                           double r, int roundCorner = wxPDF_CORNER_ALL, int style = wxPDF_STYLE_DRAW);

  /// Draws a Bezier curve
  
  virtual void Curve(double x0, double y0, double x1, double y1,
                     double x2, double y2, double x3, double y3,
                     int style = wxPDF_STYLE_DRAW);

  /// Draws an ellipse
  
  virtual void Ellipse(double x0, double y0, double rx, double ry = 0, 
                       double angle = 0, double astart = 0, double afinish = 360,
                       int style = wxPDF_STYLE_DRAW, int nSeg = 8, bool doSector = false);

  /// Draws a circle
  
  virtual void Circle(double x0, double y0, double r, 
                      double astart = 0, double afinish = 360,
                      int style = wxPDF_STYLE_DRAW, int nSeg = 8);

  /// Draws a sector
  
  virtual void Sector(double x0, double y0, double r, double astart, double afinish,
                      int style = wxPDF_STYLE_FILLDRAW, bool clockwise = true, double origin = 90.);

  /// Draws a polygon
  
  virtual void Polygon(const wxPdfArrayDouble& x, const wxPdfArrayDouble& y,
                       int style = wxPDF_STYLE_DRAW);

   /// Draws a regular polygon
  
  virtual void RegularPolygon(double x0, double y0, double r, int ns, double angle = 0, bool circle = false,
                              int style = wxPDF_STYLE_DRAW, 
                              int circleStyle = wxPDF_STYLE_DRAW,
                              const wxPdfLineStyle& circleLineStyle = wxPdfLineStyle(),
                              const wxPdfColour& circleFillColour = wxPdfColour());

  /// Draws a star polygon
  
  virtual void StarPolygon(double x0, double y0, double r, int nv, int ng, double angle = 0, bool circle = false,
                           int style = wxPDF_STYLE_DRAW, 
                           int circleStyle = wxPDF_STYLE_DRAW,
                           const wxPdfLineStyle& circleLineStyle = wxPdfLineStyle(),
                           const wxPdfColour& circleFillColour = wxPdfColour());

  /// Draws a Bezier spline through a list of points
  
  virtual void BezierSpline(const wxPdfArrayDouble& x, const wxPdfArrayDouble& y, int style);

  /// Draws a closed Bezier spline through a list of points
  
  virtual void ClosedBezierSpline(const wxPdfArrayDouble& x, const wxPdfArrayDouble& y, int style);

  /// Draws a shape
  
  virtual void Shape(const wxPdfShape& shape, int style = wxPDF_STYLE_DRAW);

  /// Performs a rotation around a given center.
  
  virtual void Rotate(double angle, double x = -1, double y = -1);

  /// Sets the font embedding mode
  
  virtual void SetFontSubsetting(bool fontSubsetting = true) { m_fontSubsetting = fontSubsetting; }

  /// Returns the font embedding mode
  
  virtual bool GetFontSubsetting() const { return m_fontSubsetting; }

  /// Imports a TrueType, TrueTypeUnicode or Type1 font and makes it available.
  
  virtual bool AddFont(const wxString& family, 
                       const wxString& style = wxEmptyString, 
                       const wxString& file = wxEmptyString);

  /// Imports a CJK (Chinese, Japanese or Korean) font and makes it available.
  
#if wxUSE_UNICODE
  virtual bool AddFontCJK(const wxString& family);
#else
  virtual bool AddFontCJK(const wxString& family) 
  { 
    wxUnusedVar(family);
    return false;
  }
#endif
  
  /// Sets the font used to print character strings. 
  
  virtual bool SetFont(const wxString& family,
                       const wxString& style = wxEmptyString,
                       double size = 0);
  
  /// Sets the font used to print character strings. 
  
  virtual bool SetFont(const wxString& family, int style, double size = 0);
  
  /// Sets the font used to print character strings based on a wxFont object.
  
  virtual bool SetFont(const wxPdfFont& font, int style = wxPDF_FONTSTYLE_REGULAR, double size = 0);

  /// Sets the font used to print character strings based on a wxFont object.
  
  virtual bool SetFont(const wxFont& font);

  /// Defines the size of the current font.
  
  virtual void SetFontSize(double size);
  
  /// Returns the current font.
    
  virtual wxPdfFont GetCurrentFont() const;

  /// Returns the current font description instance.
    
  virtual const wxPdfFontDescription& GetFontDescription() const;
  
  /// Gets the font family of the current font.
  
  virtual const wxString GetFontFamily();

  /// Gets the style of the current font.
  
  virtual const wxString GetFontStyle() const;
  
  /// Gets the style of the current font.
  
  virtual int GetFontStyles() const;
  
  /// Gets the size of the current font.
  
  virtual double GetFontSize() const;

  /// Creates a new internal link and returns its identifier.
  
  virtual int AddLink();
  
  /// Defines the page and position a link points to.
  
  virtual bool SetLink(int link, double y = 0., int page = -1);
  
  /// Puts a link on a rectangular area of the page.
  
  virtual void Link(double x, double y, double w, double h, const wxPdfLink& link);

  /// Adds a bookmark to the document outline
  
  virtual void Bookmark(const wxString& txt, int  level = 0, double y = 0);

  /// Prints a character string.
  
  virtual void Text(double x, double y, const wxString& txt);

  /// Prints a rotated text string
  
  virtual void RotatedText(double x, double y, const wxString& txt, double angle);

  /// Prints a rotated text string with explicit rotation center
  
  virtual void RotatedText(double textX, double textY, double rotationX, double rotationY, const wxString& txt, double angle);

  /// Whenever a page break condition is met,
  
  virtual bool AcceptPageBreak();
  
  /// Prints a cell (rectangular area) with optional borders, background colour and character string.
  
  virtual void Cell(double w, double h = 0., const wxString& txt = wxEmptyString,
                    int border = wxPDF_BORDER_NONE, int ln = 0, 
                    int align = wxPDF_ALIGN_LEFT, int fill = 0, 
                    const wxPdfLink& link = wxPdfLink(-1));

  /// This method allows printing text with line breaks.
  
  virtual int MultiCell(double w, double h, const wxString& txt,
                        int border = 0, int align = wxPDF_ALIGN_JUSTIFY,
                        int fill = 0, int maxline = 0);

  /// This method counts the number of lines a text would occupy in respect to a given maximal width
  
  virtual int LineCount(double w, const wxString& txt);

  /// This method counts the number of lines a text will occupy in respect to a given maximal width
  
  virtual int TextBox(double w, double h, const wxString& txt,
                      int halign = wxPDF_ALIGN_JUSTIFY, int valign = wxPDF_ALIGN_TOP,
                      int border = 0, int fill = 0);

  /// This method prints text from the current position.
  
  virtual void Write(double h, const wxString& txt, const wxPdfLink& link = wxPdfLink(-1));

  /// This method prints text with cell attributes from the current position.
  
  virtual void WriteCell(double h, const wxString& txt, int border = wxPDF_BORDER_NONE, int fill = 0, const wxPdfLink& link = wxPdfLink(-1));

  /// Prints an array of glyphs identified by glyph numbers from the current position.
  
  virtual bool WriteGlyphArray(wxPdfArrayDouble& x, wxPdfArrayDouble& y, wxPdfArrayUint32& glyphs);

  /// Puts an image in the page. 
  
  virtual bool Image(const wxString& file, double x, double y, double w = 0, double h = 0, 
                     const wxString& mimeType = wxEmptyString,
                     const wxPdfLink& link = wxPdfLink(-1),
                     int maskImage = 0);

  
  virtual bool Image(const wxString& name, const wxImage& image,
                     double x, double y, double w = 0, double h = 0,
                     const wxPdfLink& link = wxPdfLink(-1),
                     int maskImage = 0, bool jpegFormat = false, int jpegQuality = 75);

  
  virtual bool Image(const wxString& name, wxInputStream& stream,
                     const wxString& mimeType,
                     double x, double y, double w = 0, double h = 0,
                     const wxPdfLink& link = wxPdfLink(-1),
                     int maskImage = 0);

  
  virtual int ImageMask(const wxString& file, const wxString& mimeType = wxEmptyString);

  
  virtual int ImageMask(const wxString& name, const wxImage& image);

  
  virtual int ImageMask(const wxString& name, wxInputStream& stream, const wxString& mimeType);

  /// Puts a rotated image in the page. 
  
  virtual void RotatedImage(const wxString& file, double x, double y, double w, double h,
                            double angle,
                            const wxString& type = wxEmptyString,
                            const wxPdfLink& link = wxPdfLink(-1),
                            int maskImage = 0);

  /// Get x coordinate of bottom right corner of last inserted image
  
  virtual double GetLastImageBottomRightX() { return m_img_rb_x; }

  /// Get y coordinate of bottom right corner of last inserted image
  
  virtual double GetLastImageBottomRightY() { return m_img_rb_y; }

  /// Performs a line break.
  
  virtual void Ln(double h = -1);

  /// Returns the abscissa of the current position.
  
  virtual double GetX();
  
  /// Defines the abscissa of the current position. 
  
  virtual void SetX(double x);
  
  /// Returns the ordinate of the current position.
  
  virtual double GetY();
  
  /// Moves the current abscissa back to the left margin and sets the ordinate. 
  
  virtual void SetY(double y);
  
  /// Defines the abscissa and ordinate of the current position. 
  
  virtual void SetXY(double x, double y);
  
  /// Saves the document to a file on disk
  
  virtual void SaveAsFile(const wxString& name = wxEmptyString);
  
  /// Closes the document and returns the memory buffer containing the document
  
  virtual const wxMemoryOutputStream& CloseAndGetBuffer();

  /// Define text as clipping area
  
  virtual void ClippingText(double x, double y, const wxString& txt, bool outline = false);

  /// Define rectangle as clipping area
  
  virtual void ClippingRect(double x, double y, double w, double h, bool outline = false);

  /// Define ellipse as clipping area
  
  virtual void ClippingEllipse(double x, double y, double rx, double ry = 0, bool outline = false);

  /// Define polygon as clipping area
  
  virtual void ClippingPolygon(const wxPdfArrayDouble& x, const wxPdfArrayDouble& y, bool outline = false);

  /// Start defining a clipping path
  
  virtual void ClippingPath();

  /// Begin a new subpath
  
  virtual void MoveTo(double x, double y);

  /// Append a straight line segment to the current (sub)path
  
  virtual void LineTo(double x, double y);

  /// Append a cubic Bezier curve to the current (sub)path
  
  virtual void CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);

  /// End a graphics path
  
  virtual void EndPath(int style = wxPDF_STYLE_DRAW);

  /// Close the clipping path
  
  virtual void ClosePath(int style = wxPDF_STYLE_NOOP);

  /// Define clipping area using a shape
  
  virtual void ClippingPath(const wxPdfShape& shape, int style = wxPDF_STYLE_NOOP);

  /// Remove clipping area
  
  virtual void UnsetClipping();

  /// Prints a cell clipped to a rectangular area
  
  virtual void ClippedCell(double w, double h = 0., const wxString& txt = wxEmptyString,
                           int border = wxPDF_BORDER_NONE, int ln = 0, 
                           int align = wxPDF_ALIGN_LEFT, int fill = 0, 
                           const wxPdfLink& link = wxPdfLink(-1));

  /// Enters a transformation environment
  
  virtual void StartTransform();

  /// Performs scaling in X direction only
  
  virtual bool ScaleX(double sx, double x = -1, double y = -1);

  /// Performs scaling in Y direction only
  
  virtual bool ScaleY(double sy, double x = -1, double y = -1);

  /// Performs equal scaling in X and Y direction
  
  virtual bool ScaleXY(double s, double x = -1, double y = -1);

  /// Performs scaling in X and Y direction
  
  virtual bool Scale(double sx, double sy, double x = -1, double y = -1);

  /// Performs a horizontal mirroring transformation
  
  virtual void MirrorH(double x = -1);

  /// Performs a vertical mirroring transformation
  
  virtual void MirrorV(double y = -1);

  /// Moves the X origin
  
  virtual void TranslateX(double tx);

  /// Moves the Y origin
  
  virtual void TranslateY(double ty);

  /// Moves the origin
  
  virtual void Translate(double tx, double ty);

  /// Performs a skewing in both X direction only
  
  virtual bool SkewX(double xAngle, double x = -1, double y = -1);

  /// Performs a skewing in Y direction only
  
  virtual bool SkewY(double yAngle, double x = -1, double y = -1);

  /// Performs a skewing in both X and Y directions
  
  virtual bool Skew(double xAngle, double yAngle, double x = -1, double y = -1);

  virtual void Transform( double a, double b, double c, double d, double tx, double ty );

  /// Leaves a transformation environment
  
  virtual void StopTransform();

  /// Sets alpha values and blend mode
  
  virtual int SetAlpha(double lineAlpha = 1, double fillAlpha = 1, wxPdfBlendMode blendMode = wxPDF_BLENDMODE_NORMAL);

  /// Sets a previously defined alpha state
  
  virtual void SetAlphaState(int alphaState);

  /// Defines a linear gradient shading
  
  virtual int LinearGradient(const wxPdfColour& col1, const wxPdfColour& col2,
                             wxPdfLinearGradientType gradientType = wxPDF_LINEAR_GRADIENT_HORIZONTAL);

  /// Defines a axial gradient shading
  
  virtual int AxialGradient(const wxPdfColour& col1, const wxPdfColour& col2,
                            double x1 = 0, double y1 = 0,
                            double x2 = 1, double y2 = 0,
                            double intexp = 1);

  /// Defines a axial gradient shading
  
  virtual int MidAxialGradient(const wxPdfColour& col1, const wxPdfColour& col2,
                               double x1 = 0, double y1 = 0,
                               double x2 = 1, double y2 = 0,
                               double midpoint = 0.5, double intexp = 1);

  /// Defines a radial gradient shading
  
  virtual int RadialGradient(const wxPdfColour& col1, const wxPdfColour& col2, 
                              double x1 = 0.5, double y1 = 0.5, double r1 = 0,
                              double x2 = 0.5, double y2 = 0.5, double r2 = 1,
                              double intexp = 1);

  /// Defines a coons patch mesh gradient shading
  
  virtual int CoonsPatchGradient(const wxPdfCoonsPatchMesh& mesh, double minCoord = 0, double maxCoord = 1);

  /// Paints a gradient shading to rectangular area
  
  virtual void SetFillGradient(double x, double y, double w, double h, int gradient);

  /// Draws a graphical marker symbol
  
  virtual void Marker(double x, double y, wxPdfMarker markerType, double size);

  /// Adds a text annotation
  
  virtual void Annotate(double x, double y, const wxString& text);

  /// Appends Javascript
  
  virtual void AppendJavascript(const wxString& javascript);

  /// Prints a string containing simple XML markup
  
  virtual void WriteXml(const wxString& str);

  /// Adds a check box field at the current position
  
  virtual void CheckBox(const wxString& name, double width, bool checked = false);

  /// Adds a check box field
  
  virtual void CheckBox(const wxString& name, double x, double y, double width, bool checked = false);
  
  /// Adds a combo box field at the current position
  
  virtual void ComboBox(const wxString& name, double width, double height, const wxArrayString& values);

  /// Adds a combo box field
  
  virtual void ComboBox(const wxString& name, 
                        double x, double y, double width, double height, 
                        const wxArrayString& values);
  
  /// Adds a push button at the current position
  
  virtual void PushButton(const wxString& name, double width, double height, 
                          const wxString& caption, const wxString& action);

  /// Adds a push button
  
  virtual void PushButton(const wxString& name, double x, double y, double width, double height, 
                          const wxString& caption, const wxString& action);
  
  /// Adds a radio button at the current position
  
  virtual void RadioButton(const wxString& group, const wxString& name, double width);
  
  /// Adds a radio button
  
  virtual void RadioButton(const wxString& group, const wxString& name, 
                           double x, double y, double width);

  /// Adds a text field at the current position
  
  virtual void TextField(const wxString& name, double width, double height,
                         const wxString& value = wxEmptyString, bool multiline = false);

  /// Adds a text field
  
  virtual void TextField(const wxString& name, 
                         double x, double y, double width, double height,
                         const wxString& value = wxEmptyString, bool multiline = false);

  /// Sets colours for form fields
  
  virtual void SetFormColours(const wxPdfColour& borderColour = wxPdfColour(),
                     const wxPdfColour& backgroundColour = wxPdfColour(250),
                     const wxPdfColour& textColour = wxPdfColour());

  /// Sets the border style for form fields
  
  virtual void SetFormBorderStyle(wxPdfBorderStyle borderStyle = wxPDF_BORDER_SOLID,
                                  double borderWidth = -1);

  /// Starts a new Template
  
  virtual int BeginTemplate(double x = 0, double y = 0, double width = 0, double height = 0);

  /// Terminates a template
  
  virtual int EndTemplate();

  /// Get the calculated size of a template
  
  virtual void GetTemplateSize(int templateId, double& width, double& height);

  /// Uses a template in current page or in another template
  
  virtual void UseTemplate(int templateId, double x = -1, double y = -1, double width = 0, double height = 0);

  /// Sets a source file for the external template feature.
  
  virtual int SetSourceFile(const wxString& filename, const wxString& password = wxEmptyString);
  
  /// Gets the document information dictionary of the current external PDF document.
  
  virtual bool GetSourceInfo(wxPdfInfo& info);

  /// Imports a page from an external PDF document
  
  virtual int ImportPage(unsigned int pageno, wxPdfPageBox pageBox = wxPDF_PAGEBOX_ARTBOX);

  /// Gets the bounding box of a template
  
  virtual void GetTemplateBBox(int templateId, double& x, double& y, double& width, double& height);

  /// Sets the bounding box of a template
  
  virtual void SetTemplateBBox(int templateId, double x, double y, double width, double height);

  /// Prints a text string along a path defined by a shape
  
  virtual void ShapedText(const wxPdfShape& shape, const wxString& text, wxPdfShapedTextMode mode = wxPDF_SHAPEDTEXTMODE_STRETCHTOFIT);

  /// Add a layer
  
  virtual wxPdfLayer* AddLayer(const wxString& layerName);

  /// Add a title layer
  
  virtual wxPdfLayer* AddLayerTitle(const wxString& layerTitle);

  /// Add a layer membership container
  
  virtual wxPdfLayerMembership* AddLayerMembership();

  /// Lock a layer
  
  virtual void LockLayer(wxPdfLayer* layer);

  /// Add a radio group of layers
  
  virtual void AddLayerRadioGroup(const wxPdfLayerGroup& radioGroup);

  /// Enter a layer
  
  virtual void EnterLayer(wxPdfLayer* layer);
  virtual void EnterLayer(wxPdfLayerMembership* layer);

  /// Leave a layer
  
  virtual void LeaveLayer();

  /// Attach file
  
  virtual bool AttachFile(const wxString& fileName, 
                          const wxString& attachName = wxEmptyString,
                          const wxString& description = wxEmptyString);

  /// Set message translation mode
  
  void SetMessageTranslateMode(bool translate) { m_translate = translate; }

  /// Get message translation mode
  
  bool GetMessageTranslateMode() { return m_translate; }

protected:
  /// Initialize
  virtual void Initialize(int orientation);

  /// Save graphic state
  virtual void SaveGraphicState();

  /// Restore graphic state
  virtual void RestoreGraphicState();

  /// Clear graphic state
  virtual void ClearGraphicState();

  /// Select font
  virtual bool SelectFont(const wxString& family,
                          const wxString& style = wxEmptyString,
                          double size = 0, bool setFont = true);

  /// Select font
  virtual bool SelectFont(const wxString& family, int style,
                          double size = 0, bool setFont = true);

  /// Select font based on wxFont object
  virtual bool SelectFont(const wxFont& font, bool setFont = true);

  /// Select font based on wxFont object
  virtual bool SelectFont(const wxPdfFont& font, int style, double size = 0, bool setFont = true);

  /// Force selecting the current font
  virtual void ForceCurrentFont();

  /// Defines the size of the current font.
  
  virtual void SetFontSize(double size, bool setSize);
  
  /// Apply visual ordering
  virtual wxString ApplyVisualOrdering(const wxString& txt);

  /// Returns the length of a string in user unit.
  
  virtual double DoGetStringWidth(const wxString& s);

  /// Prints a cell (rectangular area) with optional borders, background colour and character string.
  
  virtual void DoCell(double w, double h = 0., const wxString& txt = wxEmptyString,
                      int border = wxPDF_BORDER_NONE, int ln = 0, 
                      int align = wxPDF_ALIGN_LEFT, int fill = 0, 
                      const wxPdfLink& link = wxPdfLink(-1));

  /// Start document
  virtual void BeginPage(int orientation, wxSize pageSize);
  
  /// End of page contents
  virtual void EndPage();
  
  /// End dociment
  virtual void EndDoc();

  /// Add header
  virtual void PutHeader();
  
  /// Add pages.
  virtual void PutPages();

  /// Replace page number aliases
  virtual void ReplaceNbPagesAlias();
  
  /// Add resources
  virtual void PutResources();

  /// Add bookmarks
  virtual void PutBookmarks();

  /// Add extended graphics states
  virtual void PutExtGStates();

  /// Add shaders
  virtual void PutShaders();

  /// Adds fonts
  virtual void PutFonts();
  
  /// Add images
  virtual void PutImages();

  /// Add templates
  virtual void PutTemplates();

  /// Add imported objects
  virtual void PutImportedObjects();

  virtual void WriteObjectValue(wxPdfObject* value, bool newline = true);

  /// Add spot colours
  virtual void PutSpotColours();

  /// Add patterns
  virtual void PutPatterns();

  /// Add layers
  virtual void PutLayers();

    void PutOCProperties();

    void PutOCGOrder(wxPdfLayer* layer);

    void PutASEvent(const wxString& situation, const wxString& category, bool& first);

  /// Add Javascript (document level)
  virtual void PutJavaScript();

  /// Add attached files
  virtual void PutFiles();

  /// Add resource dictionary
  virtual void PutResourceDict();
  
  /// Add encryption info.
  virtual void PutEncryption();

  /// Add form fields
  virtual void PutFormFields();

  /// Add info.
  virtual void PutInfo();
  
  /// Addcatalog
  virtual void PutCatalog();
  
  /// Add object dictionary
  virtual void PutXObjectDict();
  
  /// Add trailer
  virtual void PutTrailer();

  /// Calculate stream size
  size_t CalculateStreamLength(size_t len);

  /// Calculate stream offset
  size_t CalculateStreamOffset();

  /// Get new object id
  int GetNewObjId();

    void NewObj(int objId = 0);
  
  /// Decorate text
  wxString DoDecoration(double x, double y, const wxString& txt);

    void ShowText(const wxString& txt);

    void ShowGlyph(wxUint32 glyph);

    void TextEscape(const wxString& s, bool newline = true);

    void PutStream(wxMemoryOutputStream& s);
  
    void OutTextstring(const wxString& s, bool newline = true);

    void OutRawTextstring(const wxString& s, bool newline = true);

    void OutHexTextstring(const wxString& s, bool newline = true);

    void OutAsciiTextstring(const wxString& s, bool newline = true);
  
    void OutEscape(const char* s, size_t len);

    void OutAscii(const wxString& s, bool newline = true);

    void Out(const char* s, bool newline = true);

    void Out(const char* s, size_t len, bool newline = true);

    void OutPoint(double x, double y);

    void OutPointRelative(double dx, double dy);

    void OutLine(double x, double y);

    void OutLineRelative(double dx, double dy);

    void OutCurve(double x1, double y1, double x2, double y2, double x3, double y3);

    void Transform(double tm[6]);

    void AddFormField(wxPdfAnnotationWidget* field, bool setFormField = true);

    void OutIndirectObject(wxPdfIndirectObject* object);

    void OutImage(wxPdfImage* currentImage,
                double x, double y, double w, double h, const wxPdfLink& link);

    void WriteXml(wxXmlNode* node);

    void PrepareXmlCell(wxXmlNode* node, wxPdfCellContext& context);

    void WriteXmlCell(wxXmlNode* node, wxPdfCellContext& context);

    void DoXmlAlign(wxPdfCellContext& context);

    void PrepareXmlTable(wxXmlNode* node, wxPdfCellContext& context);

    void WriteXmlTable(wxPdfCellContext& context);

    void SetScaleFactor(const wxString& unit);

  wxSize CalculatePageSize(wxPaperSize format);

  wxSize CalculatePageSize(double pageWidth, double pageHeight);

  virtual void AddPage(int orientation, wxSize pageSize);

  void LoadZapfDingBats();

private:
  bool                 m_yAxisOriginTop;      ///< flag whether the origin of the y axis resides at the top (or bottom) of the page
  int                  m_page;                ///< current page number
  int                  m_n;                   ///< current object number
  int                  m_firstPageId;         ///< object id of the first page
 
  wxPdfOffsetHashMap*  m_offsets;             
  wxOutputStream*      m_buffer;              ///< buffer holding in-memory PDF
  wxPdfPageHashMap*    m_pages;               ///< array containing pages
  int                  m_state;               
  bool                 m_kerning;             ///< kerning flag
  bool                 m_compress;            ///< compression flag
  int                  m_defOrientation;      ///< default orientation
  int                  m_curOrientation;      ///< current orientation
  wxPdfBoolHashMap*    m_orientationChanges;  ///< array indicating orientation changes
  wxSize               m_defPageSize;         ///< default page width
  wxSize               m_curPageSize;         ///< current page width
  wxPdfPageSizeMap*    m_pageSizes;           
  double               m_k;                   ///< scale factor (number of points in user unit)
  double               m_fwPt;                ///< width of page format in points
  double               m_fhPt;                ///< height of page format in points
  double               m_fw;                  ///< width of page format in user unit
  double               m_fh;                  ///< height of page format in user unit
  double               m_wPt;                 ///< current width of page in points
  double               m_hPt;                 ///< current height of page in points
  double               m_w;                   ///< current width of page in user unit
  double               m_h;                   ///< current height of page in user unit
  double               m_imgscale;            
  double               m_tMargin;             ///< top margin
  double               m_bMargin;             ///< page break margin
  double               m_lMargin;             ///< left margin
  double               m_rMargin;             ///< right margin
  double               m_cMargin;             
  double               m_x;                   ///< current x position in user unit for cell positioning
  double               m_y;                   ///< current y position in user unit for cell positioning
  double               m_angle;               ///< current rotation angle
  double               m_lasth;               ///< height of last cell printed
  double               m_lineWidth;           ///< line width in user units
  wxPdfLineStyle       m_lineStyle;           ///< current line style
  int                  m_fillRule;            
  int                  m_inTransform;         ///< flag for transformation state
  wxPdfFontHashMap*    m_fonts;               ///< array of used fonts
  wxPdfStringHashMap*  m_diffs;               ///> array of encoding differences
  wxPdfBoolHashMap*    m_winansi;             ///> array of flags whether encoding differences are based on WinAnsi
  wxPdfImageHashMap*   m_images;              ///< array of used images
  wxPdfPageLinksMap*   m_pageLinks;           ///< array of links in pages
  wxPdfLinkHashMap*    m_links;               ///< array of internal links
  wxPdfNamedLinksMap*  m_namedLinks;          
  wxPdfExtGStateMap*   m_extGStates;          ///< array of extended graphics states
  wxPdfExtGSLookupMap* m_extGSLookup;         ///< array for fast lookup of extended graphics states
  int                  m_currentExtGState;    
  wxPdfGradientMap*    m_gradients;           ///< array of gradients
  wxPdfSpotColourMap*  m_spotColours;          ///< array of spot colours
  wxPdfPatternMap*     m_patterns;            
  wxPdfAnnotationsMap* m_annotations;         ///< array of text annotations
  
  wxArrayPtrVoid       m_outlines;            ///< array of bookmarks
  int                  m_outlineRoot;         ///< number of root node
  int                  m_maxOutlineLevel;     
  wxArrayPtrVoid       m_graphicStates;       ///< array of graphic states
  wxString             m_fontPath;            ///< current default path for font files
  wxString             m_fontFamily;          ///< current font family
  int                  m_fontStyle;           ///< current font style
  int                  m_decoration;          ///< font decoration flags
  bool                 m_fontSubsetting;      
  wxPdfFontDetails*    m_currentFont;         
  double               m_fontSizePt;          ///< current font size in points
  double               m_fontSize;            ///< current font size in user unit
  wxPdfColour          m_drawColour;          ///< commands for drawing colour
  wxPdfColour          m_fillColour;          ///< commands for filling colour
  wxPdfColour          m_textColour;          ///< commands for text colour
  bool                 m_colourFlag;          ///< indicates whether fill and text colours are different
  double               m_ws;                  ///< word spacing
  wxPdfTextRenderMode  m_textRenderMode;      
  bool                 m_autoPageBreak;       ///< automatic page breaking
  double               m_pageBreakTrigger;    ///< threshold used to trigger page breaks
  bool                 m_inFooter;            ///< flag set when processing footer
  wxPdfZoom            m_zoomMode;            ///< zoom display mode
  double               m_zoomFactor;          ///< zoom factor
  wxPdfLayout          m_layoutMode;          ///< layout display mode
  int                  m_viewerPrefs;         
  wxString             m_title;               ///< title
  wxString             m_subject;             ///< subject
  wxString             m_author;              ///< author
  wxString             m_keywords;            ///< keywords
  wxString             m_creator;             ///< creator
  wxString             m_aliasNbPages;        ///< alias for total number of pages
  wxString             m_PDFVersion;          
  double               m_img_rb_x;            ///< right-bottom corner X coordinate of inserted image
  double               m_img_rb_y;            
  // Encryption
  bool                 m_encrypted;           ///< flag whether document is protected
  wxPdfEncrypt*        m_encryptor;           ///< encryptor instance
  int                  m_encObjId;            
  // Javascript
  int                  m_nJS;                 ///< Javascript object number
  wxString             m_javascript;          
  // Forms
  int                  m_zapfdingbats;        ///< index of font ZapfDingBats
  wxPdfFormFieldsMap*  m_formFields;          ///< array of form fields
  wxPdfFormAnnotsMap*  m_formAnnotations;     ///< array of form field annotations
  wxPdfRadioGroupMap*  m_radioGroups;         ///< array of radio button groups
  wxString             m_formBorderColour;     ///< form field border colour
  wxString             m_formBackgroundColour; ///< form field background colour
  wxString             m_formTextColour;       ///< form field text colour
  wxString             m_formBorderStyle;     ///< form field border style
  double               m_formBorderWidth;     
  // Templates
  bool                 m_inTemplate;          ///< flag whether template mode is on
  wxPdfTemplatesMap*   m_templates;           ///< array of templates
  wxString             m_templatePrefix;      ///< prefix used for template object names
  int                  m_templateId;          ///< Id of current template
  wxPdfTemplate*       m_currentTemplate;     
  wxPdfParserMap*      m_parsers;             ///< array of parsers
  wxPdfParser*         m_currentParser;       ///< current parser
  wxString             m_currentSource;       ///< current import source file name
  wxString             m_importVersion;       
  // OCG / layer
  wxPdfOcgMap*         m_ocgs;                ///< array of OCGs
  wxPdfLayerRGMap*     m_rgLayers;            ///< array of radio group layers
  wxPdfLayerGroup*     m_lockedLayers;        ///< array of locked layers
  wxArrayInt           m_layerDepth;          
  // File attachments
  int                  m_nAttachments;        ///< attachments object number
  wxPdfAttachmentMap*  m_attachments;         
  bool                 m_translate;           
private:
#if WXPDFDOC_INHERIT_WXOBJECT
  DECLARE_DYNAMIC_CLASS(wxPdfDocument)
#endif
  DECLARE_NO_COPY_CLASS(wxPdfDocument)

  friend class wxPdfImage;
  friend class wxPdfTable;
};

#endif
